#!/usr/bin/env python
#
# Copyright 2011 kokorohamoe@gmail.com
#


from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
import urllib
import re
import hashlib
import datetime
from google.appengine.ext import db
from google.appengine.api import users

class DBshortURL(db.Model):
  url      = db.StringProperty()
  short  = db.StringProperty()
  site     = db.StringProperty()
  author = db.UserProperty()
  date = db.DateTimeProperty(auto_now_add=True)


def base62encode(number, alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'):
    """Convert positive integer to a base36 string."""
    if not isinstance(number, (int, long)):
        raise TypeError('number must be an integer')
 
    # Special case for zero
    if number == 0:
        return alphabet[0]
 
    base = ''
 
    sign = ''
    if number < 0:
        sign = '-'
        number = - number
 
    while number != 0:
        number, i = divmod(number, len(alphabet))
        base = alphabet[i] + base
 
    return sign + base




class MainHandler(webapp.RequestHandler):
    def get(self,a):
	url = urllib.unquote(a);
	site = re.match("http(s)?://([^/]*)", url) 
        self.response.out.write('<?xml version="1.0" encoding="UTF-8" ?>\n');
	if site==None :
	        self.response.out.write('<shorturl>')
       		self.response.out.write('<error>')
		self.response.out.write('URL ERROR')
	        self.response.out.write('</error>')
	        self.response.out.write('</shorturl>')
		return;
	md5 = hashlib.md5()
	md5.update(url)
	digest = md5.hexdigest()
	number = int(digest, 16)%56800235583
# DEBUG
#	number = 1
	number62 = base62encode(number)
        site = site.group(2)
	datas = db.GqlQuery("SELECT * FROM DBshortURL  WHERE url != :1 AND short = :2 AND site = :3", url, number62, site).get();
	while datas != None:
	    number+=1;
    	    number62 = base62encode(number)
	    datas = db.GqlQuery("SELECT * FROM DBshortURL  WHERE url != :1 AND short = :2 AND site = :3", url, number62, site).get();

        self.response.out.write('<shorturl>\n')		        		
 	self.response.out.write('\t<url>')
	self.response.out.write(url)
        self.response.out.write('</url>\n')
	self.response.out.write('\t<site>')
	self.response.out.write(site)
        self.response.out.write('</site>\n')
	self.response.out.write('\t<short>')
	self.response.out.write(number62)
        self.response.out.write('</short>\n')

# DEBUG
#        self.response.out.write('\t</conflict>')
#	datas = db.GqlQuery("SELECT * FROM DBshortURL  WHERE url != :1 AND short = :2 AND site = :3", url, number62, site).get();
#	if datas == None:
#	        self.response.out.write('None')
#	else:
#	        self.response.out.write(datas.url)
#        self.response.out.write('</conflict>\n')
        self.response.out.write('</shorturl>')

        shortModel = DBshortURL()
        if users.get_current_user():
            shortModel.author = users.get_current_user()
        shortModel.url = url
        shortModel.site = site
        shortModel.short = number62
        shortModel.put()



def main():
    application = webapp.WSGIApplication([(r'/shorturl/(.*)', MainHandler)
                                     ],
                                     debug=True)

    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()
